
#ifndef  INDEX_H
#define  INDEX_H
#include "common.h"

/*  
 *  key = 1, value = 0x01020304;
 *  data.insert(key, value);
 *  auto index = getIndex("applyTime")
 *  ik = index.parseKey(value)
 *  insert(ik, key);
 * 
 */

class Index{
public:
    explicit Index(const std::string & name)
    :name(name)
    {
    }
    virtual ~Index(){
    }

    const std::string & getName() const { return name; }
    void setName(const std::string & name) { this->name = name;}

    virtual std::shared_ptr<std::vector<int>> rangeScan(int offset, int count, bool isAscend) = 0;

    virtual int insert(const std::string & key, const int pk) = 0;
    virtual int update(const std::string & key, const int pk) = 0;
    virtual int remove(const std::string & key, const int pk) = 0;
    virtual int remove(const std::string & key) = 0;

    virtual int parseKey(const char * value, std::string & outKey) = 0;

    virtual int clear() = 0;

    virtual std::string toString() const = 0;
    
private:
    std::string name;
};

class StringIndex : public Index {
public:
    typedef std::string IndexKeyType;
    typedef int PrimaryKeyType;
    typedef std::vector<PrimaryKeyType> PkArray;
    typedef std::set<PrimaryKeyType> PkContainter;
    typedef std::map<IndexKeyType, PkContainter*> IndexMap;

    explicit StringIndex(const std::string & name);
    virtual ~StringIndex();

    std::shared_ptr<PkArray> rangeScan(int offset, int count, bool isAscend) override;

    int insert(const std::string & key, const PrimaryKeyType pk) override;
    int update(const std::string & key, const PrimaryKeyType pk) override;
    int remove(const std::string & key) override;
    int remove(const std::string & key, const PrimaryKeyType pk) override;
    int clear() override;

    std::string toString() const override;

private:
    IndexMap index;
};

#endif   /* INDEX_H */
